import re
from typing import Any

import scrapy
from scrapy.http import Response

from apps.tender_project.tender_project.base.base_project_spider import BaseProjectSpider
from apps.tender_project.tender_project.items import NetProjectInfoItem
from apps.tender_project.tender_project.utils.re_ import XING
from utils.tools import parse_url_params


class QgAnhuiProject(BaseProjectSpider):
    name = 'qg_anhui_project'
    source = "安徽省全国公共交易平台"
    url = "https://ggzy.ah.gov.cn/jsgc/list"
    province = "安徽省"
    start_urls = [
        "https://ggzy.ah.gov.cn/jsgc/list?tenderProjectType=1",
        "https://ggzy.ah.gov.cn/jsgc/list?tenderProjectType=2",
        "https://ggzy.ah.gov.cn/jsgc/list?tenderProjectType=3",
        "https://ggzy.ah.gov.cn/jsgc/list?tenderProjectType=4",
        "https://ggzy.ah.gov.cn/zfcg/list",
    ]

    custom_settings = {
        "COOKIES_ENABLED": False
    }

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url)

    def parse(self, response: Response, **kwargs: Any) -> Any:
        total_page = response.xpath('.').re_first(r"共(\d+)页")
        url = response.url.split("?")[0]
        if 'zfcg' in url:
            for i in range(1, int(total_page) + 1):
                data = {
                    "currentPage": str(i),
                    "time": "",
                    "bulletinNature": "3",
                    "jyptId": "",
                    "region": ""
                }
                yield scrapy.FormRequest(
                    url,
                    formdata=data,
                    callback=self.parse_list,
                    meta={"currentPage": i},
                )
        else:
            tender_project_type = response.url.split("tenderProjectType=")[1]
            for i in range(1, int(total_page) + 1):
                data = {
                    "currentPage": str(i),
                    "tenderProjectType": str(tender_project_type),
                    "bulletinNature": "3",
                    "jyptId": "",
                    "region": ""
                }
                yield scrapy.FormRequest(
                    url,
                    formdata=data,
                    callback=self.parse_list,
                    meta={"currentPage": i},
                )

    def parse_list(self, response: Response, **kwargs: Any) -> Any:
        for i in response.xpath("//*[@class='list-item']"):
            url = i.xpath(".//a/@href").get()
            city = i.xpath("//span[contains(@class, 'area')]/text()").get().replace("【", "").split("-")[0]
            get_date = self.process_date(i.xpath("string(.)").get())
            _, params = parse_url_params(url)
            source_url = response.urljoin(url)
            url = "https://ggzy.ah.gov.cn/jsgc/newDetailSub"
            data = {
                "type": "zbjg",
                "bulletinNature": params['bulletinNature'],
                "guid": params['guid'],
                "statusGuid": ""
            }
            yield scrapy.FormRequest(
                url, formdata=data, callback=self.parse_detail,
                meta={"city": city, "get_date": get_date, "source_url": source_url}
            )

    def parse_detail(self, response, **kwargs):

        title = response.xpath("//*[contains(@class, 'article-title')]/text()").get()

        data_string_pro = re.sub(r"[\n\t\r\s]", "",
                                 "".join(response.xpath("/html/body/div[2]").xpath("//text()").getall()))
        try:
            data_string = self.del_html_tag(response.text)
        except:
            data_string = data_string_pro

        base_item = dict(
            source=self.source,
            province=self.province,
            city=response.meta["city"],
            data_type="中标结果",
            source_url=response.meta['source_url'],
            get_date=response.meta["get_date"],
            title=title,
        )
        rules = {
            "project_date": [
                r"定标日期[:：为\s]+\s*([^\n]{3,100})",
                r"定标时间[:：为\s]+\s*([^\n]{3,100})",
                r"中标日期[:：为\s]+\s*([^\n]{3,100})",
                r"中标时间[:：为\s]+\s*([^\n]{3,100})",
                r"开标日期[:：为\s]+\s*([^\n]{3,100})",

            ],
            "review_names": [
                r"名单[:：为\s]+\s*([^\n]{3,100})",
                r"成员[:：为\s]+\s*([^\s]{3,100})"
            ],
            "register_num": [
                r"编号[:：为\s]+\s*([\(\)a-zA-Z\d-]{2,25})",
                r"编 号\s[:：为\s]\s+\s*([^\s]{3,100})"
            ],
            "project_name": [
                r"项目名称及标书编号[:：为]?\s*(.{2,100})\s*",
                r"项目名称及编号[:：为]?\s*(.{2,100})\s*",
                r"项目名称[:：为]?\s*(.{2,100})\s*",
                r"招标条件\s*(.{2,100})\s*已具备招标条件",
                r"本工程\s*(.{2,100})\s*已",
                r"工程名称\s*([^\s]{2,100})\s*",
                r"分包名称\s*([^\s]{2,100})\s*",
                r"组织的[:：为]?\s*(.{2,100})\s*"
            ],
            "budget_amount": [
                r"总预算金额[:：为]+\s*([^预算\n]{1,100})",
                r"成交金额[:：为]+\s*([^预算\n]{1,100})",
                r"中标价(万元)[:：为]+\s*([^预算\n]{1,100})",
                r"中标金额[:：为]+\s*([^预算\n]{1,100})",
                r"预算金额[:：为]?\s*([^预算\n]{1,100})\s*",
                r"预算金额[:：为]?\s*([^预算]{1,100})\s*",
                r"估算价[:：为]?\s*([^预算\n]{1,100})\s*",
                r"投资额及来源[:：为]?\s*([^预算\n]{1,100})\s*",
                r"采购项目预算金额（元）[:：为]?\s*([^预算\n]{1,100})\s*",
            ],
        }
        item = self.gen_item_with_reg(
            data_string,
            rules,
            base_item,
            need_check=["project_name"],
            html=response.text,
        )
        project_info_rules = {
            'project_name': [
                ['主要投标标的名称', "主要响应标的名称"],
                []
            ],
            'term': [
                ['服务期限'], []
            ],
            'people_num': [
                ['服务团队人数'], []
            ],
            'brand': [
                ['品牌'], []
            ],
            'num': [
                ['数量'], []
            ],
            'desc': [
                ['服务要求或者标的基本概况'], []
            ],
            'model': [
                ['规格型号'], []
            ],
            'price': [
                ['单价'], []
            ],
            'ar_name': [
                ['拟派项目经理'], []
            ],
        }
        for table in response.xpath("//table"):
            project_info = self.gen_item_with_table(table=[table], rules=project_info_rules, item={}, more=True)
            project_info = [i for i in project_info if i.get("project_name")]
            if project_info:
                item["project_info"] = project_info
                break
        # 拒绝的供应商
        project_refuse_info_rules = {
            'com_name': [
                ['投标人名称'],
                []
            ],
            'reason': [
                ['被拒绝原因'], []
            ],
            'detail': [
                ['招标文件相应拒绝条款'], []
            ],
        }
        for table in response.xpath("//table"):
            project_refuse_info = self.gen_item_with_table([table], project_refuse_info_rules, {}, more=True)
            project_refuse_info = [i for i in project_refuse_info if i.get("com_name")]
            if project_refuse_info:
                item["project_refuse_info"] = project_refuse_info
                break

        project_company_item_regs = {
            "com_name": [
                r"供应商名称[:：为]+\s*([^\s]{3,100})",
                # r"中标人[:：为]?\s*([^\s]{3,100})",
                r'供应商名称[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'中签人名称[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'中[签标]单位[名称]{0,2}[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'中标[(（成交)）]{0,4}供应商名单[:：]?([^\d，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'[中成][选标交][信息人为名称：:（\s]+([^\d在从，。；：\:\&\,\.]{5,18}[司厂院所队])',
                r'[中成]\s*[选标交]\s*[信息人为名称：:（\s]+([^\d在从，。；：\:\&\,\.]{5,18}[司厂院所队])',
                r'中标[（(]成交[)）]单位[名称]{0,2}[:：]{0,1}([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'(?:[中成承][交标包][人单位供应服务商社会资本]{1,4}方?|[供应服务商]{3,5}|标段[一1])[、，名称为：:（]*([^\d，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'第一[中标（）成交]{0,6}候选人[名称]{0,2}[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'成交候选人第一[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'被选中单位[企业]{0,2}[名称]{0,2}[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'[中标成交]{2}候选人[名称单为]{0,3}[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
                r'(?:排[序名]第[一1]的?[候侯选人单位]{2,3}|第[一1]的?拟?中[选标包][候侯选人排序名公司单位]{3,5}|第[一1]名|第[一1]排序人)[名称为：:（]*([^\d在从，。；：\:\&\,\.]{5,19}[司厂院所队])',
                r'通知书([^\d，。；：\:\&\,\.]{5,18}?[司厂院所队])[：:]',
                r'[确拟如评结抽审][论取定下核][1\.\.、排序第一是由，：:]*([^\d在从，。；：\:\&\,\.]{5,18}?[司院所队])',
                r'[联合体牵头人]{3}[名称为：:]*([^\d，。；：\:\&\,\.]{5,18}?[司厂院所队])',
                r'候选人.{0,5}1[\.\.、]([^\d在从，。；：\:\&\,\.]{5,18}?[司厂院所队])',
                r'[入中][选围]单位[信息名称]{1,4}[:：]?([^\d在从，。；：\:\&\,\.]{5,20}[司厂院所队])',
            ],
            "price": [
                r"中标.{1,6}金额[:：为]+\s*([^\n]{3,100})",
                r"中标价.{1,6}\s*([^\n]{3,100})",
                r'/费率（%）\s*([\d\.零壹贰叁肆伍陆柒捌玖拾佰仟一二三四五六七八九十百￥千万人民币亿大¥写发包价元%‰率为()（）：,，:\s]+)',
                r'(?:[￥¥]|RMB)([0-9，：.万元:,]*)',
                r'中标金额（费率、单价等）([\d零壹贰叁肆伍陆柒捌玖拾佰仟十百￥千万人民币亿大¥写发包价元%‰率()（）.,，\s]+)',
                r'[中投成承分]\s*[选标交包]?总?\s*[价标报总选造金]\s*[格价额]为?[:：]?\s*([\d零壹贰叁肆伍陆柒捌玖拾佰仟十百￥千万人民币亿大¥写发包价元%‰率()（）.,，\s]+)',
                r'预成交价[:：]?\s*([\d\.零壹贰叁肆伍陆柒捌玖拾佰仟百￥千万人民币亿大¥写发包价元%‰率为()（）,.，\s]+)',
                r'公司\s*金额[:：]?\s*([\d零壹贰叁肆伍陆柒捌玖拾佰仟十百￥千万人民币亿大¥写发包价元%‰率为()（）.,，\s]+)',
                r'报价金额[:：]?\s*([\d\.零壹贰叁肆伍陆柒捌玖拾佰仟百￥千万人民币亿大¥写发包价元%‰率为()（）,.，\s]+)',
                r'中标（成交）(?:价|金额)[:：]?\s*([\d\.零壹贰叁肆伍陆柒捌玖拾佰仟百￥千万人民币亿大¥写发包价元%‰率为()（）,.，\s]+)',
                r'合同金额[:：]?\s*([\d\.零壹贰叁肆伍陆柒捌玖拾佰仟百￥千万人民币亿大¥写发包价元%‰率为()（）,.，\s]+)',
            ],
            'ar_name': [
                r'项目负责人（项目经理/项目总监）[:：]?\s*([' + XING + r']\w{1,2})',
                r'(?:项目|设计)(?:负责人|经理)(?:名称|姓名|为|是|)?(?:及证书编号)?[:：]?\s*([' + XING + r']\w{1,2})',
                r'总监理工程师(?:姓名)?[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目负责人姓名及其(?:相关)?证书名称和编号[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目经理姓名及资格证书号码[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目经理姓名及资格证书号码[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目负责人（项目经理）[:：]?\s*([' + XING + r']\w{1,2})',
                r'监理师[:：]?\s*([' + XING + r']\w{1,2})',
                r'建造师[:：]?\s*([' + XING + r']\w{1,2})',
                r'(?:项目负责人|项目经理)（建造师）[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目负责人（项目经理/项目总监）[:：]?\s*([' + XING + r']\w{1,2})',
                r'项目总监(?:（项目经理/项目负责人）)?[:：]?\s*([' + XING + r']\w{1,2})',
                r'[^委员会][建目负][造经责总][师理人监].{0,20}姓[名为：:]\s*([^\d，。；：\:\&\,\./]{2,3})'],
            "address": [
                r"供应商地址[:：为]+\s*([^\s]{3,100})"
            ],
            "duration": [
                r'工期.{0,5}?(\d*?个?[年月日天])'
            ],
        }

        project_company_item = self.gen_item_with_reg(
            data_string,
            project_company_item_regs,
            {},
            need_check=["com_name"],
            html=response.text,
        )
        if project_company_item.get("com_name"):
            item["project_company_info"] = [project_company_item]
        else:
            project_company_item_rules = {
                'com_name': [
                    ['中标人', '中标单位', '供应商', '成交单位', '成交供应商', '成交人', '单位名称', '中标候选',
                     '公司名称', '中标人名称', '中标供应商', '中标供应商名称', '中标候选人', '中标候选人名称',
                     '中标单位', '中标单位名称', '中标商名称',
                     '中标（成交）供应商名称', '中标（成交）候选人名称', '供应商名称', '入围供应商', '入围供应商名称',
                     '成交人', '成交供应商',
                     '成交供应商名称', '成交候选人名称', '成交候选供应商名称', '成交单位', '投标供应商', '投标单位',
                     '预成交供应商名称', '中标候选人名称',
                     '中标公司名称', '拟中标人(施工)', '中标人', '单位名称', '企业名称', '投标人名称',
                     '第一中标候选人'],
                    ['地址', '代码', '排名', '证书', '标的', '顺序', '标段', '情况']
                ],
                'price': [
                    ['总价', '元', '结果', '金额', '成交价', '标报价', '成交总额', '中标价', '价格', '成交报价',
                     '单价', '中标价格', '中标金额', '中标金额(元)', '中标金额（万元）', '中标金额（元）',
                     '中标金额（单位：人民币元）', '中标（成交）价格（元）',
                     '中标（成交）金额（元）', '成交价格', '成交金额', '成交金额(元)', '成交金额（元）', '投标报价',
                     '投标报价（元）', '报价(万元)', '报价(元)',
                     '报价/元', '报价（元）', '预成交金额(元)', '预算金额', '金额（元）', '中标金额(万元)', '中标价(元)',
                     '中标价', '中标价（元）', '最终报价',
                     '投标报价（单位：元）', '标的金额（元）', '中标价（万元）', '中标价', '投标价（元）', '投标报价(元)',
                     '中标价（万元） ', '中标价（万元）',
                     '中标价(万元)', '第一轮报价（元）', '投标报价（万元）', '报价', ], ['评', '审查']
                ],
                'candidate': [
                    ["候选人", "序号"], [""]
                ],
                'duration': [
                    ['工期', '工期（天）', ], []
                ],
                'ar_name': [
                    ['项目经理', '负责人', '姓名', '建造师名称', '项目负责人', '项目负责人及其建造师注册证书号',
                     '项目经理', '项目负责人及证号', '项目经理及证书号', '总监理工程师', '项目总监',
                     '项目负责人姓名及注册证书编号', '拟定项目经理姓名和注册证书编号', '拟定项目负责人姓名',
                     '拟定项目负责人姓名和注册证书编号', '拟定项目总监姓名和注册证书编号',
                     '拟定项目总监姓名和注册号', '姓名', ], ['号']
                ],
                'address': [
                    ['地址'], []
                ],
            }
            for table in response.xpath("//table"):
                project_company_info = self.gen_item_with_table([table], project_company_item_rules, {},
                                                                more=True)
                project_company_info = [i for i in project_company_info if i.get("com_name")]
                if project_company_info:
                    item["project_company_info"] = project_company_info
                    break
        yield NetProjectInfoItem(**item)


if __name__ == '__main__':
    from scrapy import cmdline

    cmdline.execute("scrapy crawl qg_anhui_project".split())
